from pydantic import BaseModel, validator, Field
from typing import Optional, Dict
from datetime import datetime
from database.models import OrderStatus


class OrderCreate(BaseModel):
    """订单创建验证器"""
    user_id: int
    product_id: int
    model_3d_id: int
    quantity: int
    unit_price: float
    custom_material: Optional[str] = None
    custom_size: Optional[str] = None
    custom_color: Optional[str] = None
    custom_params: Optional[Dict] = None
    shipping_address: str
    shipping_name: str
    shipping_phone: str
    
    @validator('user_id', 'product_id', 'model_3d_id')
    def validate_id(cls, v):
        if v <= 0:
            raise ValueError('ID必须大于0')
        return v
    
    @validator('quantity')
    def validate_quantity(cls, v):
        if v <= 0:
            raise ValueError('数量必须大于0')
        if v > 1000:
            raise ValueError('单次订购数量不能超过1000')
        return v
    
    @validator('unit_price')
    def validate_unit_price(cls, v):
        if v <= 0:
            raise ValueError('单价必须大于0')
        if v > 999999.99:
            raise ValueError('单价不能超过999999.99')
        return round(v, 2)
    
    @validator('shipping_address')
    def validate_shipping_address(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('收货地址不能为空')
        if len(v) > 500:
            raise ValueError('收货地址长度不能超过500个字符')
        return v.strip()
    
    @validator('shipping_name')
    def validate_shipping_name(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('收货人姓名不能为空')
        if len(v) > 50:
            raise ValueError('收货人姓名长度不能超过50个字符')
        return v.strip()
    
    @validator('shipping_phone')
    def validate_shipping_phone(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('收货人电话不能为空')
        if len(v) != 11 or not v.isdigit():
            raise ValueError('收货人电话必须是11位数字')
        return v


class OrderUpdate(BaseModel):
    """订单更新验证器"""
    status: Optional[OrderStatus] = None
    payment_status: Optional[str] = None
    payment_method: Optional[str] = None
    tracking_number: Optional[str] = None
    
    @validator('payment_status')
    def validate_payment_status(cls, v):
        if v is not None and v not in ['pending', 'paid', 'failed', 'refunded']:
            raise ValueError('支付状态只能是: pending, paid, failed, refunded')
        return v


class OrderSearch(BaseModel):
    """订单搜索验证器"""
    order_number: Optional[str] = None
    user_id: Optional[int] = None
    product_id: Optional[int] = None
    status: Optional[OrderStatus] = None
    payment_status: Optional[str] = None
    start_date: Optional[datetime] = None
    end_date: Optional[datetime] = None
    
    @validator('start_date', 'end_date')
    def validate_dates(cls, v):
        return v


class ProductionJobCreate(BaseModel):
    """生产任务创建验证器"""
    order_id: int
    manufacturer_id: int
    production_file_url: str
    file_format: str
    material_specification: str
    quantity: int
    priority: int = 1
    estimated_completion_date: Optional[datetime] = None
    
    @validator('order_id', 'manufacturer_id')
    def validate_id(cls, v):
        if v <= 0:
            raise ValueError('ID必须大于0')
        return v
    
    @validator('production_file_url')
    def validate_production_file_url(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('生产文件URL不能为空')
        return v.strip()
    
    @validator('file_format')
    def validate_file_format(cls, v):
        allowed_formats = ['stl', 'obj', 'step', 'iges', '3mf']
        if v.lower() not in allowed_formats:
            raise ValueError(f'不支持的文件格式，支持的格式: {", ".join(allowed_formats)}')
        return v.lower()
    
    @validator('material_specification')
    def validate_material_specification(cls, v):
        if not v or len(v.strip()) == 0:
            raise ValueError('材质规格不能为空')
        if len(v) > 200:
            raise ValueError('材质规格长度不能超过200个字符')
        return v.strip()
    
    @validator('quantity')
    def validate_quantity(cls, v):
        if v <= 0:
            raise ValueError('数量必须大于0')
        return v
    
    @validator('priority')
    def validate_priority(cls, v):
        if v < 1 or v > 5:
            raise ValueError('优先级必须在1-5之间')
        return v


class ProductionJobUpdate(BaseModel):
    """生产任务更新验证器"""
    status: Optional[str] = None
    progress_percentage: Optional[int] = None
    production_cost: Optional[float] = None
    material_cost: Optional[float] = None
    labor_cost: Optional[float] = None
    quality_check_passed: Optional[bool] = None
    quality_notes: Optional[str] = None
    
    @validator('status')
    def validate_status(cls, v):
        if v is not None and v not in ['pending', 'assigned', 'in_progress', 'completed', 'failed']:
            raise ValueError('任务状态只能是: pending, assigned, in_progress, completed, failed')
        return v
    
    @validator('progress_percentage')
    def validate_progress_percentage(cls, v):
        if v is not None:
            if v < 0 or v > 100:
                raise ValueError('进度百分比必须在0-100之间')
            return v
        return v
    
    @validator('production_cost', 'material_cost', 'labor_cost')
    def validate_cost(cls, v):
        if v is not None:
            if v < 0:
                raise ValueError('成本不能为负数')
            return round(v, 2)
        return v
    
    @validator('quality_notes')
    def validate_quality_notes(cls, v):
        if v is not None and len(v) > 500:
            raise ValueError('质检备注长度不能超过500个字符')
        return v


class OrderResponse(BaseModel):
    """订单响应模型"""
    id: int
    order_number: str
    user_id: int
    product_id: int
    model_3d_id: int
    quantity: int
    unit_price: float
    total_amount: float
    status: str
    payment_status: str
    payment_method: Optional[str]
    shipping_address: str
    shipping_name: str
    shipping_phone: str
    tracking_number: Optional[str]
    custom_material: Optional[str]
    custom_size: Optional[str]
    custom_color: Optional[str]
    custom_params: Optional[str]  # JSON字符串
    created_at: datetime
    paid_at: Optional[datetime]
    shipped_at: Optional[datetime]
    delivered_at: Optional[datetime]
    
    class Config:
        from_attributes = True